package com.sffzh.util.format;

import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;

import net.sf.json.JSONObject;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.annotations.Expose;
import com.sffzh.constant.Time;
import com.sffzh.pojo.User;

/**
 * 与Message是相对的一组工具，用于解析来自手机的参数
 * 解析标准格式为
 * {
 * param:{}
 * ,code:123
 * ,method:""
 * ,time:""
 * }
 * 格式无法作为json解析或者公共参数param,code,method的格式不符，或者三个参数均缺失时将招抛出异常
 * @author sffzh
 *
 */
public class Param {

	@Expose
	private String method;
	@Expose
	private int code;
	private String timeStr;
	private long timeDiff=-1;
	private int mill=(int) (System.currentTimeMillis()%100000000);
	@Expose
	private Date time;
	private Date localTime=new Date();
	@Expose
	private Object param;
	private JSONObject paramObject;
	private JSONObject json;
	private String jsonString;
	
	public Param(String jsonParam,String method,int code) throws JSONPatternWrongExeption{
		this(JSONObject.fromObject(jsonParam),method,code);
	}
	
	/**
	 * 手动创建一个Param对象以模拟一个标准param参数
	 * @param objectParam
	 * @param method
	 * @param code
	 */
	public Param(Object objectParam,String method,int code){
		this.param=objectParam;
		setParam(JSONObject.fromObject(objectParam));;
		setMethod(method);
		setCode(code);
		setTime(new Date());
		this.jsonString=createParamStr();
	}
	
	public String createParamStr(){
		GsonBuilder builder=new GsonBuilder();
		builder.setDateFormat(Time.getPatternStr(Time.Pattern.DEFAULT));
		return builder.create().toJson(this);
	}
	
	/**
	 * 用于将请求参数中的时间与当前系统时间进行取差，返回差值，差值单位为秒
	 * 若未传递时间值，则返回-1。
	 * @return
	 */
	public long timeDiff(){
		return  timeDiff ;
	}
	
	public long getFullCode(){
		Calendar cal=Calendar.getInstance();
		cal.setTime(localTime);
		long year=cal.get(Calendar.YEAR);
		long mon=cal.get(Calendar.MONTH)+1;
		long date=cal.get(Calendar.DATE);
		return (long) (year*10E12+mon*10E10+date*10E8+code);
	}
	public int millDiff(){
		System.out.println(mill+"<<<mill");
		return mill-code;
	}
	
	private void setTimeDiff(){
		if(time!=null){
			this.timeDiff=  Math.abs((localTime.getTime()-time.getTime())/1000);
		}
	}
	
	public String getTimeStr() {
		return timeStr;
	}

	public void setTimeStr(String timeStr) {
		try {
			this.time=DateUtil.parseDateTime(timeStr);
			this.timeStr = timeStr;
			setTimeDiff();
		} catch (ParseException e) {
			e.printStackTrace();
		}
	}

	public Date getTime() {
		return time;
	}

	public void setTime(Date time) {
		this.timeStr=DateUtil.formatDateTime(time);
		this.time = time;
		setTimeDiff();
	}
	public Param(String json) throws JSONPatternWrongExeption{
		if(json==null)throw new JSONPatternWrongExeption("对象为null");
		setJsonString(json);
	}
	
	/**
	 * 获取param中的关键字,是json中的param中的json对象，不包括最外层公共字段
	 * @param paramKey
	 * @return
	 */
	public Object get(String paramKey){
		return paramObject.get(paramKey);
	}
	
	public boolean contains(String paramKey){
		return paramObject.containsKey(paramKey);
	}
	
	public int getInt(String paramKey){
		return paramObject.getInt(paramKey);
	}
	
	public String getString(String paramKey){
		return paramObject.getString(paramKey);
	}
	
	/**
	 * 当对param对象进行设置json变量的操作时，所有该对象的成员变量 都会同步更新
	 * @param json
	 * @throws Exception 
	 */
	public void setJsonString(String json) throws JSONPatternWrongExeption {
		setJson(JSONObject.fromObject(json));
	}

	public String getMethod() {
		return method;
	}

	public void setMethod(String method) {
		this.method = method;
	}

	public int getCode() {
		return code;
	}

	public void setCode(int code) {
		this.code = code;
	}

	public JSONObject getParam() {
		return paramObject;
	}

	public void setParam(JSONObject param) {
		this.paramObject = param;
	}

	public JSONObject getJson() {
		return json;
	}

	/**
	 * 当对param对象进行设置json变量的操作时，所有该对象的成员变量 都会同步更新
	 * @param json
	 * @throws Exception 
	 */
	public void setJson(JSONObject json) throws JSONPatternWrongExeption {
		this.json = json;
		if(json==null){
			this.jsonString=null;
			this.method=null;
			this.code=0;
		}else 
			try {
				this.jsonString=json.toString();
				this.json=json;
				this.method=this.json.containsKey("method")?this.json.getString("method"):null;
				if(this.json.containsKey("param"))this.paramObject=this.json.getJSONObject("param");
				if(this.json.containsKey("code"))this.code=this.json.getInt("code");
				if(this.json.containsKey("time")){
					try {
						setTimeStr(this.json.getString("time"));
					} catch (Exception e) {
						e.printStackTrace();
						System.err.println("传入的json参数中time格式不正确");
					}
				}
				if(this.method==null&&this.code==0&&this.paramObject==null){
					throw new JSONPatternWrongExeption("参数未包含任何有效内容！");
				}
			} catch (Exception e) {
				throw new JSONPatternWrongExeption("传入的json参数格式不正确！");
			}

	}

	public String getJsonString() {
		return jsonString;
	}
	
	public String toString(){
		return jsonString;
	}
	
	public static void main(String[] args) throws Exception {
		User u=new User();
		u.setBirthday(new Date());
		Param p=new Param(u,"",123);
		System.out.println(p);
	}

	/**
	 * 如果param中的数据可以对应一个bean类，则可用此方法映射还原这个类，返回object可以强转类型
	 * @param class1
	 * @return
	 */
	public Object getBean(Class<?> class1) {
		Gson g=new Gson();
		return g.fromJson(this.paramObject.toString(), class1);
	}
}
